/* $Id: adcread.c,v 1.1 2003/12/09 22:43:28 GrosbaJ Exp $ */
#include <p18f87j50.h>
#include <spi_cidei_87j50.h>
//
///********************************************************************
//*    Function Name:  ReadADC                                        *
//*    Return Value:   int, A/D result                                *
//*    Parameters:     void                                           *
//*    Description:    This routine reads the ADRESL and ADRESH       *
//*                    and returns these as a long.                   *
//********************************************************************/
//int ReadADC(void)
//{
//  union ADCResult i; // A union is used to read the
//                     // A/D result due to issues with
//                     // handling long variables
//
//  i.br[0] = ADRESL;  // Read ADRESL into the lower byte
//  i.br[1] = ADRESH;  // Read ADRESH into the high byte
//
//  return (i.lr);     // Return the long variable
//}
//
///****************************************************************
//*    Function Name:  BusyADC                                    *
//*    Return Value:   char: 1 - A/D busy, 0 - Done converting    *
//*    Parameters:     void                                       *
//*    Description:    This routine checks the GO bit to see if   *
//*                    the A/D conversion is done.                *
//****************************************************************/
//char BusyADC(void)
//{
//  /* If the GO bit is set then A/D is busy converting
//   * Otherwise A/D is done converting
//   */
//  return(ADCON0bits.GO_DONE);
//
//}
//
///********************************************************************
//*    Function Name:  ConvertADC                                     *
//*    Return Value:   void                                           *
//*    Parameters:     void                                           *
//*    Description:    This routine starts an A/D conversion by       *
//*                    setting the GO bit.                            *
//********************************************************************/
//void ConvertADC(void)
//{
//  ADCON0bits.GO_DONE = 1;  // Set the GO bit to start a conversion
//}
//
///********************************************************************
//*    Function Name:  OpenADC                                        *
//*    Return Value:   void                                           *
//*    Parameters:     config: bit definitions to configure A/D       *
//*                    channel: channel selection                     *
//*    Description:    This routine first resets the A/D registers    *
//*                    to the POR state and then configures the       *
//*                    A/D clock, interrupt, justification, vref      *
//*                    source, and I/O.  It also sets the channel.    *
//*    Notes:          The bit definitions for config and channel     *
//*                    can be found in the adc16.h file.              *
//********************************************************************/
//void OpenADC( void)
//{
//// Reset A/D Registers to POR state
//
////configuracion del adc/////////////////////////
//ADCON1=0x0E;
//ADCON0=0x00;
//ADCON2=0xFE;
//ADCON0bits.ADON=1;
///////////////////////
//
//    ADCON0bits.ADON = 1;         // Enable the A/D
//}
//
///************************************************************************
//*    Function Name:  CloseADC                                           *
//*    Return Value:   void                                               *
//*    Parameters:     void                                               *
//*    Description:    This routine turns the A/D off and disables        *
//*                    the A/D interrupt                                  *
//************************************************************************/
//void CloseADC(void)
//{
//  ADCON0bits.ADON = 0;
//  PIE1bits.ADIE = 0;
//}
//

/********************************************************************
*     Function Name:    WriteSPI                                    *
*     Return Value:     Status byte for WCOL detection.             *
*     Parameters:       Single data byte for SPI bus.               *
*     Description:      This routine writes a single byte to the    * 
*                       SPI bus.                                    *
********************************************************************/
unsigned char WriteSPI( unsigned char data_out )
{
  SSPBUF = data_out;           // write byte to SSPBUF register
  if ( SSPCON1 & 0x80 )        // test if write collision occurred
   return ( -1 );              // if WCOL bit is set return negative #
  else
  {
    while( !SSPSTATbits.BF );  // wait until bus cycle complete 
  }
  return ( 0 );                // if WCOL bit is not set return non-negative#
}



/********************************************************************
*   Function Name:  OpenSPI                                         *
*   Return Value:   void                                            *
*   Parameters:     SSP peripheral setup bytes                      *
*   Description:    This function sets up the SSP module on a       * 
*                   PIC18Cxxx device for use with a Microchip SPI   *
*                   EEPROM device or SPI bus device.                *
OpenSPI(SPI_FOSC_64, MODE_00, SMPEND);
********************************************************************/
void OpenSPI( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase)
{
  SSPSTAT &= 0x3F;                // power on state 
  SSPCON1 = 0x00;                 // power on state
  SSPCON1 |= sync_mode;           // select serial mode 
  SSPSTAT |= smp_phase;           // select data input sample phase

  switch( bus_mode )
  {
    case 0:                       // SPI bus mode 0,0
      SSPSTATbits.CKE = 1;        // data transmitted on rising edge
      break;    
    case 2:                       // SPI bus mode 1,0
      SSPSTATbits.CKE = 1;        // data transmitted on falling edge
      SSPCON1bits.CKP = 1;        // clock idle state high
      break;
    case 3:                       // SPI bus mode 1,1
      SSPCON1bits.CKP = 1;        // clock idle state high
      break;
    default:                      // default SPI bus mode 0,1
      break;
  }

  switch( sync_mode )
  {
    case 4:                       // slave mode w /SS enable
#if defined(__18F6310)  || defined(__18F6390)  || \
    defined(__18F6410)  || defined(__18F6490)  || \
    defined(__18F8310)  || defined(__18F8390)  || \
    defined(__18F8410)  || defined(__18F8490)  || \
    defined(__18F6527)  || defined(__18F6622)  || \
    defined(__18F6627)  || defined(__18F6722)  || \
    defined(__18F8527)  || defined(__18F8622)  || \
    defined(__18F8627)  || defined(__18F8722)  || \
    defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || \
    defined(__18F67J10) || defined(__18F85J10) || \
    defined(__18F85J15) || defined(__18F86J10) || \
    defined(__18F86J15) || defined(__18F87J10)
      TRISFbits.TRISF7 = 1;       // define /SS pin as input

#elif defined(__18F23K20) || defined(__18F24K20) || \
      defined(__18F25K20) || defined(__18F26K20) || \
      defined(__18F43K20) || defined(__18F44K20) || \
      defined(__18F45K20) || defined(__18F46K20)

      TRISAbits.TRISA5 = 1;       // define /SS1 pin as input
      ANSELbits.ANS4 = 0;         // disable analog function

#else

      TRISAbits.TRISA5 = 1;       // define /SS pin as input
#endif

    case 5:                       // slave mode w/o /SS enable
#if defined(__18F2455) || defined(__18F2550) || \
    defined(__18F4455) || defined(__18F4550)
      TRISBbits.TRISB1 = 1;       // define clock pin as input
#else
      TRISCbits.TRISC3 = 1;       // define clock pin as input
#endif
      SSPSTATbits.SMP = 0;        // must be cleared in slave SPI mode
      break;

    default:                      // master mode, define clock pin as output
#if defined(__18F2455) || defined(__18F2550) || \
    defined(__18F4455) || defined(__18F4550)
      TRISBbits.TRISB1 = 0;       // define clock pin as output
#else
      TRISCbits.TRISC3 = 0;       // define clock pin as output
#endif
      break;
  }

#if defined(__18F2455) || defined(__18F2550) || \
    defined(__18F4455) || defined(__18F4550)
  TRISC &= 0x7F;                  // define SDO as output (master or slave)
  TRISB |= 0x01;                  // define SDI as input (master or slave)
#else
  TRISC &= 0xDF;                  // define SDO as output (master or slave)
  TRISC |= 0x10;                  // define SDI as input (master or slave)
#endif
  SSPCON1 |= SSPENB;              // enable synchronous serial port 
}
